package encaps.action;

import encaps.entities.OrderType;
import encaps.entities.Role;
import encaps.resources.Config;
import encaps.security.RoleManager;
import encaps.utils.StringUtil;
import encaps.utils.SystemException;
import encaps.utils.search.*;
import java.util.HashMap;
import java.util.Map;

public abstract class AbstractSearchAction extends Action {

    public static final String PERSON = "person";
    public static final String USER = "user";
    public static final String MOVIE = "movie";
    public static final String PAGE = "page";
    public static final String ORDER_COLUMN = "orderCol";
    public static final String ORDER_TYPE = "orderType";
    public static final String SHOW_SEARCH_FORM_ONLY = "formOnly";
    protected ActionContext actionContext;
    protected static final Map<String, Searcher> searchers;

    static {
        searchers = new HashMap<String, Searcher>();
        Searcher movieSearcher = new MovieSearcher();
        searchers.put(MOVIE, movieSearcher);
        Searcher personSearcher = new PersonSearcher();
        searchers.put(PERSON, personSearcher);
        Searcher userSearcher = new UserSearcher();
        searchers.put(USER, userSearcher);
    }

    protected SearchContext getSearchContext() throws SystemException {
        SearchContext context = createEmptySearchContext();
        fillContextWithSearchingParameters(context);
        fillContextWithPagingParameters(context);

        Role userRole = RoleManager.getRoleManager().getRole(actionContext.getUserRole());
        context.setUserRole(userRole);

        context.setOrderColumn(actionContext.getTextParameter(ORDER_COLUMN));
        String orderTypeName = actionContext.getTextParameter(ORDER_TYPE);
        context.setOrderType(OrderType.getOrderType(orderTypeName));

        return context;
    }

    protected int getPageNumber() throws SystemException {
        String pageParameter = actionContext.getTextParameter(PAGE);
        int page;
        if (StringUtil.isEmpty(pageParameter)) {
            page = 1;
        } else {
            page = Integer.parseInt(pageParameter);
        }
        return page;
    }

    protected void fillContextWithPagingParameters(SearchContext context)
            throws SystemException {
        int pageNumber = getPageNumber();
        context.setPage(pageNumber);
        int recordsPerPage = Config.getRecordsPerPage();
        context.setRecordsPerPage(Config.getRecordsPerPage());
        int fromRecord = (pageNumber - 1) * recordsPerPage;
        context.setFromRecord(fromRecord);
    }

    protected abstract SearchContext createEmptySearchContext();

    /**
     * Fills Search context with searching parameters, notable
     * <code>entityType</code> (for basic search),
     * <code>searching parameter (-s)</code> and
     * <code>searching action</code> name.
     *
     * @param context context to fill.
     */
    protected abstract void fillContextWithSearchingParameters(SearchContext context)
            throws SystemException;
}
